#include "Application.h"

Application::Application(SDLEngine* engine) {
	this->server = NULL;
	this->cliente = NULL;
	this->engine = engine;
}

Application::~Application() {

}


void* Application::run() {
	Event* event;

	while (engine->isRunning()) {

		event = this->engine->getLasEvent();
		if (event == NULL) {
			continue;
		}

		switch (event->getType()) {
			case UserEvent:
				handleUserEvent(*event);
				break;
			default:
				break;
		}

	}

	return NULL;

}

void Application::handleUserEvent(Event event) {
	std::string host;
	int separador;
	std::string port;
	std::string user;
	SocketProtocoloPlano* socket;

	switch (event.getCode()) {
	case PLAY:{
		//Puede definir de donde vienen las conexiones, ip y puerto
		//Formato esperado= IP:PUERTO
		separador = event.getData().find_first_of(':');
		host = event.getData().substr(0, separador);
		port = event.getData().substr(separador + 1);
		user = event.getData2();

		socket = new SocketProtocoloPlano();
		if (socket->connect(host, UtilString::stringToInt(port)) != 0) {
			Logger::log("Application", "handleUserEvent", "Fallo la Conexion");
			break;
		}

		Logger::log("Application", "handleUserEvent", "Conexion iniciada");

		cliente = new Client(user, host, socket, engine);
		cliente->start();

	}
		break;
	case CREATE: {

		//Puede definir de donde vienen las conexiones, ip y puerto
		//Formato esperado= IP:PUERTO
		separador = event.getData().find_first_of(':');
		host = event.getData().substr(0, separador);
		port = event.getData().substr(separador + 1);

		//Avoid to have multiple instance of server running in the same machine
		if (this->server != NULL && this->server->isRunning()) {
			Logger::log("Application", "handleUserEvent",
					"Otra instancia de server esta corriendo.");
			break;
		}

		//Data 2 tiene el nombre del scenario
		std::string scenarioName = event.getData2();
		this->server = new Servidor(scenarioName);

		//Inicio el listener
		server->iniciar(UtilString::stringToInt(port), SERVER_MAX_QUEUE);

		//Inicio el server que replica los mensajes
		server->start();

		Logger::log("Application", "handleUserEvent", "Server iniciado");
	}
		break;
	case EXIT:
		terminar();
		break;
	default:
		break;
	}
}

void Application::terminar() {
	engine->stop();

	if (this->server != NULL) {
		this->server->terminar();
		this->server->join();
		this->server = NULL;
	}

	if (this->cliente != NULL) {
		this->cliente->terminar();
		this->cliente->join();
		this->cliente = NULL;
	}


}

